#include "DlgReportDailyNecess.h"
#include <wx/sizer.h>
#include <wx/statbox.h>
#include <wx/stattext.h>
#include <wx/msgdlg.h>
//wxFreeChart头文件
#include "wx/wxfreechartdefs.h"
#include <wx/xy/xyplot.h>
#include <wx/xy/xylinerenderer.h>
#include <wx/xy/xysimpledataset.h>
#include <wx/axis/logarithmicnumberaxis.h>
#include <wx/multiplot.h>
#include "TimeSeriesDataset.h"
//(*InternalHeaders(DlgUser)
#include <wx/intl.h>
#include <wx/string.h>
//*)

//(*IdInit(DlgUser)
//*)
const wxString CDlgReportDailyNecess::TABLENAME=_T("daily_necess");
const wxString CDlgReportDailyNecess::VIEWNAME=_T("VdailynecessFull");
const wxString WINDOWS_TEXT = _T("柴米油盐报表");

//控件ID
const long CDlgReportDailyNecess::IDC_BTN_EXIT= wxNewId();
const long CDlgReportDailyNecess::IDC_BTN_SEARCH= wxNewId();
const long CDlgReportDailyNecess::IDC_COMBO_SEARCH= wxNewId();
const long CDlgReportDailyNecess::IDC_EDIT_SEARCH= wxNewId();
const long CDlgReportDailyNecess::IDC_LIST= wxNewId();
const long CDlgReportDailyNecess::IDC_TIMEFROM= wxNewId();
const long CDlgReportDailyNecess::IDC_TIMETO= wxNewId();
const long CDlgReportDailyNecess::IDC_EDIT_STATIC= wxNewId();
const long CDlgReportDailyNecess::IDC_PIC= wxNewId();
const long CDlgReportDailyNecess::IDC_TIMER_SEC= wxNewId();

BEGIN_EVENT_TABLE(CDlgReportDailyNecess,wxDialog)
END_EVENT_TABLE()

CDlgReportDailyNecess::CDlgReportDailyNecess(wxWindow* parent,wxWindowID id,const wxPoint& pos,const wxSize& size)
    :m_Sectimer(this,IDC_TIMER_SEC)
{
    //(*Initialize(DlgUser)
    Create(parent, id, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxMINIMIZE_BOX, _T("id"));
    SetClientSize(wxDefaultSize);
    Move(wxDefaultPosition);
    //*)
    SetTitle(WINDOWS_TEXT);
    SetWindowStyle(GetWindowStyle()|wxRESIZE_BORDER|wxCLOSE_BOX|wxMAXIMIZE_BOX|wxMINIMIZE_BOX);
    CreateCtrlAndEvent();
    InitComboBoxAndListCtrl();
}

CDlgReportDailyNecess::~CDlgReportDailyNecess()
{
    //(*Destroy(DlgUser)
    //*)
}

void CDlgReportDailyNecess::CreateCtrlAndEvent()
{
    /////////创建控件并布局
    topSizer_=new wxBoxSizer(wxVERTICAL);//顶层窗口布局,从上到下包含每个了窗口布局
    wxFlexGridSizer *fir_secSize=new wxFlexGridSizer(1,2,0,0);
    fir_secSize->AddGrowableCol(0);
    wxBoxSizer *fir_secSize_l=new wxBoxSizer(wxVERTICAL);

    wxBoxSizer *firSize=new wxBoxSizer(wxHORIZONTAL);
    wxBoxSizer *secSize=new wxBoxSizer(wxHORIZONTAL);
    wxGridSizer *fifSize=new wxGridSizer(2);
    wxStaticBox* staticBox=new wxStaticBox(this,wxID_ANY,wxT("统计信息"));
    wxStaticBoxSizer *sixSize=new wxStaticBoxSizer(staticBox,wxHORIZONTAL);
    wxBoxSizer *bottomSize=new wxBoxSizer(wxHORIZONTAL);
    topSizer_->Add(fir_secSize,0,wxEXPAND|wxALL,0);
    topSizer_->Add(fifSize,10,wxEXPAND|wxALL,0);
    topSizer_->Add(sixSize,3,wxEXPAND|wxALL,0);
    topSizer_->Add(bottomSize,0,wxEXPAND|wxALL,0);

    combo_search_=new wxChoice(this,IDC_COMBO_SEARCH);
    btn_Exit_=new wxButton(this,IDC_BTN_EXIT,_T("退出"));
    btn_Search_=new wxButton(this,IDC_BTN_SEARCH,_T("查询"));
    text_search_=new wxTextCtrl(this,IDC_EDIT_SEARCH,wxEmptyString);
    list_=new wxListCtrl(this,IDC_LIST,wxDefaultPosition,wxDefaultSize,wxLC_REPORT|wxLC_SINGLE_SEL);
    timeto_=new wxDatePickerCtrl(this,IDC_TIMETO,wxDefaultDateTime,wxDefaultPosition,
                                 wxDefaultSize,wxDP_DROPDOWN|wxDP_SHOWCENTURY);
    timefrom_=new wxDatePickerCtrl(this,IDC_TIMEFROM,wxDefaultDateTime,wxDefaultPosition,
                                   wxDefaultSize,wxDP_DROPDOWN|wxDP_SHOWCENTURY);
    text_stat_=new wxTextCtrl(this,IDC_EDIT_STATIC,wxEmptyString,
                              wxDefaultPosition,wxSize(600,100),wxTE_PROCESS_ENTER|wxTE_MULTILINE|wxHSCROLL);
    chartpanel_=new wxChartPanel(this,IDC_PIC,NULL,wxDefaultPosition,wxDefaultSize);
    firSize->Add(new wxStaticText(this,wxID_ANY,_T("从")),1, wxTILE|wxALL|wxALIGN_RIGHT,5);
    firSize->Add(timefrom_,1, wxEXPAND|wxALL|wxALIGN_CENTER,5);
    firSize->Add(new wxStaticText(this,wxID_ANY,_T("到")),1, wxFIXED_MINSIZE|wxALL|wxALIGN_RIGHT,5);
    firSize->Add(timeto_,1, wxFIXED_MINSIZE|wxALL|wxALIGN_LEFT,5);
    secSize->Add(new wxStaticText(this,wxID_ANY,_T("查询类别")),1, wxTILE|wxALL|wxALIGN_RIGHT,5);
    secSize->Add(combo_search_,1, wxEXPAND|wxALL|wxALIGN_CENTER,5);
    secSize->Add(text_search_,1,wxEXPAND|wxALL|wxALIGN_CENTER,5);
    fir_secSize_l->Add(firSize,5,wxTILE|wxALL|wxALIGN_CENTER,5);
    fir_secSize_l->Add(secSize,5,wxEXPAND|wxALL,5);
    fir_secSize->Add(fir_secSize_l,10,wxEXPAND|wxALL|wxALIGN_CENTER,0);
    fir_secSize->Add(btn_Search_,0,wxEXPAND|wxALL|wxALIGN_CENTER,0);
    fifSize->Add(list_,1,wxEXPAND | wxALL,5);
    fifSize->Add(chartpanel_,1,wxEXPAND | wxALL,5);
    sixSize->Add(text_stat_,1,wxEXPAND | wxALL,5);

    bottomSize->Add(btn_Exit_,1,wxTILE|wxALL|wxALIGN_CENTER,5);

    SetSizer(topSizer_);//绑定对话框和布局控件
    SetAutoLayout(true);
    topSizer_->Fit(this);//调用对话框大小
    topSizer_->SetSizeHints(this);//设置对话框最小大小

    ///////创建事件
    Connect(IDC_BTN_EXIT,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&CDlgReportDailyNecess::OnBnClickedBtnExit);
    Connect(IDC_BTN_SEARCH,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&CDlgReportDailyNecess::OnBnClickedBtnSearch);
    Connect( wxEVT_TIMER, (wxObjectEventFunction)&CDlgReportDailyNecess::OnTimer);
    m_Sectimer.Start(1000);

    wxLogDebug(_T("CreateCtrl"));
}

void CDlgReportDailyNecess::InitComboBoxAndListCtrl()
{
    wxChoice *pchoice=wxDynamicCast(FindWindowById(IDC_COMBO_SEARCH),wxChoice);
    wxListCtrl *pList=wxDynamicCast(FindWindowById(IDC_LIST),wxListCtrl);
    pList->SetSingleStyle(wxLC_REPORT);
    pList->SetSingleStyle(wxLC_SINGLE_SEL);
    const vector<pair<wxString,wxString> >&chs_fileds_name=GetFiled_CHS_Name(_T("name_VdailynecessFull"));
    auto it=chs_fileds_name.cbegin();
    for (; it!=chs_fileds_name.cend(); ++it) {
        wxLogDebug(_T("%s "),it->first);
        pchoice->Append(it->first);
        pList->InsertColumn(pList->GetColumnCount(),it->first,wxLIST_FORMAT_LEFT,wxLIST_AUTOSIZE);
    }
    wxDateTime cur_time=wxDateTime::Now();
    cur_time.SetDay(1);//设为1号
    wxDatePickerCtrl *pDT=wxDynamicCast(FindWindowById(IDC_TIMEFROM),wxDatePickerCtrl);
    pDT->SetValue(cur_time);
    cur_time.Add(wxDateSpan::Month());//加一个月
    cur_time.Subtract(wxDateSpan::Day());//减一天，即为当月最后一天
    pDT=wxDynamicCast(FindWindowById(IDC_TIMETO),wxDatePickerCtrl);
    pDT->SetValue(cur_time);
    wxLogDebug(_T("InitComboBoxAndListCtrl"));
}


void CDlgReportDailyNecess::OnBnClickedBtnSearch(wxCommandEvent& event)
{
////////////////////////////////////////////////////////////////////////////////////////////////////////////
    wxBusyCursor waticursor;
    wxChoice *pBox=wxDynamicCast(FindWindowById(IDC_COMBO_SEARCH),wxChoice);
    int index=pBox->GetSelection();
    wxString strComboTextFirst,strComboTextSecond;
    if (index != wxNOT_FOUND) {
        strComboTextFirst=pBox->GetString(index);
    }
    wxListCtrl *pList=wxDynamicCast(FindWindowById(IDC_LIST),wxListCtrl);
    pList->DeleteAllItems();
    wxDatePickerCtrl *pDT=wxDynamicCast(FindWindowById(IDC_TIMETO),wxDatePickerCtrl);
    wxString time_to=pDT->GetValue().FormatISODate();
    pDT=wxDynamicCast(FindWindowById(IDC_TIMEFROM),wxDatePickerCtrl);
    wxString time_from=pDT->GetValue().FormatISODate();
    const vector<pair<wxString,wxString> >&chs_filed_name=GetFiled_CHS_Name(_T("name_VdailynecessFull"));
    if (chs_filed_name.empty()) {
        return;
    }
    auto it=chs_filed_name.cbegin();
    for (; it!=chs_filed_name.cend(); ++it) {
        if (strComboTextFirst==it->first) {
            strComboTextSecond=it->second;
            break;
        }
    }
    wxString listsql=_T("select dailyid,theday,typename,quantity,price,remark from ")+VIEWNAME+_T(" where date(theDay) >=date(@pa1) ")
                       _T(" and date(theDay) <=date(@pa2) ");
    wxString statsql=_T("select typename,sum(price) as price from ")+VIEWNAME+_T(" where date(theDay) >=date(@pa1) ")
                       _T(" and date(theDay) <=date(@pa2) ");
    wxTextCtrl *pText=wxDynamicCast(FindWindowById(IDC_EDIT_SEARCH),wxTextCtrl);
    wxString csEditText=pText->GetValue();
    csEditText.Trim(true);
    csEditText.Trim(false);
    if (!csEditText.IsEmpty() && !strComboTextFirst.IsEmpty()) {
        listsql+=_T(" and ")+strComboTextSecond;
        listsql+=_T(" like  '%")+csEditText+_T("%'");
        statsql+=_T(" and ")+strComboTextSecond;
        statsql+=_T(" like  '%")+csEditText+_T("%'");
    }
    statsql+=_T(" group by typename ");
    wxLogDebug(_T("listsql=%s"),listsql);
    wxLogDebug(_T("statsql=%s"),statsql);
    ////////明细查询
    sqlite3_stmt *conStat,*conList;
    if(sqlite3_prepare_v2(g_db,ToDefaultConv(listsql),LenDefaultConv(listsql),&conList,NULL)==SQLITE_OK) {
        int index1 = sqlite3_bind_parameter_index(conList, "@pa1");
        if(sqlite3_bind_text(conList, index1, ToDefaultConv(time_from), LenDefaultConv(time_from), SQLITE_STATIC)!=SQLITE_OK) {
            wxLogDebug(_T("sqlite3_bind_text on m_keyvalue_.first Error on. %s"), sqlite3_errmsg(g_db));
        }
        index1 = sqlite3_bind_parameter_index(conList, "@pa2");
        if(sqlite3_bind_text(conList, index1, ToDefaultConv(time_to), LenDefaultConv(time_to), SQLITE_STATIC)!=SQLITE_OK) {
            wxLogDebug(_T("sqlite3_bind_text on ntimeslot Error on. %s"), sqlite3_errmsg(g_db));
        }
        int row_count=0;
        while(sqlite3_step(conList)==SQLITE_ROW) {
            pList->InsertItem(row_count, _T(""));
            pList->SetItem(row_count,0,wxString((const char*)sqlite3_column_text(conList,0), DefaultConv));
            pList->SetItem(row_count,1,wxString((const char*)sqlite3_column_text(conList,1), DefaultConv));
            pList->SetItem(row_count,2,wxString((const char*)sqlite3_column_text(conList,2), DefaultConv));
            pList->SetItem(row_count,3,wxString((const char*)sqlite3_column_text(conList,3), DefaultConv));
            pList->SetItem(row_count,4,wxString((const char*)sqlite3_column_text(conList,4), DefaultConv));
            pList->SetItem(row_count++,5,wxString((const char*)sqlite3_column_text(conList,5), DefaultConv));
        }
    } else {
        wxLogDebug(_T("Error on sqlite3_prepare_v2: %s"), sqlite3_errmsg(g_db));
    }
    if (sqlite3_finalize(conList) != SQLITE_OK) {
        wxLogDebug(_T("Error on sqlite3_finalize: %s"), sqlite3_errmsg(g_db));
    }
    //汇总查询
    wxString csStat,name;
    double sumexpend=0.;
    if(sqlite3_prepare_v2(g_db,ToDefaultConv(statsql),LenDefaultConv(statsql),&conStat,NULL)==SQLITE_OK) {
        int index1 = sqlite3_bind_parameter_index(conStat, "@pa1");
        if(sqlite3_bind_text(conStat, index1, ToDefaultConv(time_from), LenDefaultConv(time_from), SQLITE_STATIC)!=SQLITE_OK) {
            wxLogDebug(_T("sqlite3_bind_text on m_keyvalue_.first Error on. %s"), sqlite3_errmsg(g_db));
        }
        index1 = sqlite3_bind_parameter_index(conStat, "@pa2");
        if(sqlite3_bind_text(conStat, index1, ToDefaultConv(time_to), LenDefaultConv(time_to), SQLITE_STATIC)!=SQLITE_OK) {
            wxLogDebug(_T("sqlite3_bind_text on ntimeslot Error on. %s"), sqlite3_errmsg(g_db));
        }
        while(sqlite3_step(conStat)==SQLITE_ROW) {
            if(sqlite3_column_text(conStat,0)!=NULL) {
                name=wxString((const char*)sqlite3_column_text(conStat,0), DefaultConv);
                sumexpend=sqlite3_column_double(conStat,1);
                csStat+=wxString::Format(_T("%s花费%f\r\n"),name,sumexpend);
                wxLogDebug(_T("%s"),csStat);
            }
        }
    } else {
        wxLogDebug(_T("Error on sqlite3_prepare_v2: %s"), sqlite3_errmsg(g_db));
    }
    if (sqlite3_finalize(conStat) != SQLITE_OK) {
        wxLogDebug(_T("Error on sqlite3_finalize: %s"), sqlite3_errmsg(g_db));
    }
    pText=wxDynamicCast(FindWindowById(IDC_EDIT_STATIC),wxTextCtrl);
    pText->SetValue(csStat);
    wxLogDebug(_T("OnBnClickedBtnSearch"));
}

void CDlgReportDailyNecess::OnBnClickedBtnExit(wxCommandEvent& event)
{
    Close();
    wxLogDebug(_T("OnBnClickedBtnExit"));
}

void CDlgReportDailyNecess::ShowData()
{
    wxListCtrl *pList=wxDynamicCast(FindWindowById(IDC_LIST),wxListCtrl);
    int itemcount=pList->GetItemCount();
    if(itemcount<=0) {
        return;
    }
    vector<pair<double,double> >oil_qua,oil_pri,rice_qua,rice_pri,gas_qua,gas_pri;
    wxString strtmp;
    double dtime,dqua,dpri;
    for (int n = 0; n < itemcount; n++) {
        strtmp=pList->GetItemText(n,1);
        strtmp.Replace(_T("-"),_T(""),true);
        strtmp.ToDouble(&dtime);
        pList->GetItemText(n,3).ToDouble(&dqua);
        pList->GetItemText(n,4).ToDouble(&dpri);
        if(pList->GetItemText(n,2).CmpNoCase(_T("食用油"))==0) {
            oil_qua.push_back(std::make_pair(dtime,dqua));
            oil_pri.push_back(std::make_pair(dtime,dpri));
        } else if(pList->GetItemText(n,2).CmpNoCase(_T("米"))==0) {
            rice_qua.push_back(std::make_pair(dtime,dqua));
            rice_pri.push_back(std::make_pair(dtime,dpri));
        } else if(pList->GetItemText(n,2).CmpNoCase(_T("煤气"))==0) {
            gas_qua.push_back(std::make_pair(dtime,dqua));
            gas_pri.push_back(std::make_pair(dtime,dpri));
        }
    }
    double *oilqua_data=NULL,*oilpri_data=NULL;
    if(oil_qua.size()>0) {
        wxASSERT(oil_qua.size()==oil_pri.size());
        oilqua_data=new double[oil_qua.size()*2];
        oilpri_data=new double[oil_pri.size()*2];
        for(size_t i=0; i<oil_qua.size(); ++i) {
            oilqua_data[i*2]  =oil_qua[i].first;
            oilqua_data[i*2+1]=oil_qua[i].second;
            oilpri_data[i*2]  =oil_pri[i].first;
            oilpri_data[i*2+1]=oil_pri[i].second;
        }
    }
    double *ricequa_data=NULL,*ricepri_data=NULL;
    if(rice_qua.size()>0) {
        wxASSERT(rice_qua.size()==rice_pri.size());
        ricequa_data=new double[rice_qua.size()*2];
        ricepri_data=new double[rice_pri.size()*2];
        for(size_t i=0; i<rice_qua.size(); ++i) {
            ricequa_data[i*2]=rice_qua[i].first;
            ricequa_data[i*2+1]=rice_qua[i].second;
            ricepri_data[i*2]=rice_pri[i].first;
            ricepri_data[i*2+1]=rice_pri[i].second;
        }
    }
    double *gasqua_data=NULL,*gaspri_data=NULL;
    if(gas_qua.size()>0) {
        wxASSERT(gas_qua.size()==gas_pri.size());
        gasqua_data=new double[gas_qua.size()*2];
        gaspri_data=new double[gas_pri.size()*2];
        for(size_t i=0; i<gas_qua.size(); ++i) {
            gasqua_data[i*2]=gas_qua[i].first;
            gasqua_data[i*2+1]=gas_qua[i].second;
            gaspri_data[i*2]=gas_pri[i].first;
            gaspri_data[i*2+1]=gas_pri[i].second;
        }
    }
    // first step: create plot
    XYPlot *plot = new XYPlot();

    // create dataset
    XYSimpleDataset *dataset = new XYSimpleDataset();

    // add two series
    if(oilpri_data) {
        dataset->AddSerie((double *) oilpri_data, oil_pri.size());
        dataset->SetSerieName(dataset->GetSerieCount()-1, wxT("油价"));
        dataset->AddSerie((double *) oilqua_data, oil_qua.size());
        dataset->SetSerieName(dataset->GetSerieCount()-1, wxT("油量"));
    }
    if(gaspri_data) {
        dataset->AddSerie((double *) gaspri_data, gas_pri.size());
        dataset->SetSerieName(dataset->GetSerieCount()-1, wxT("煤气价"));
        dataset->AddSerie((double *) gasqua_data, gas_qua.size());
        dataset->SetSerieName(dataset->GetSerieCount()-1, wxT("煤气量"));
    }
    if(ricepri_data) {
        dataset->AddSerie((double *) ricepri_data, rice_pri.size());
        dataset->SetSerieName(dataset->GetSerieCount()-1, wxT("米量"));
        dataset->AddSerie((double *) ricequa_data, rice_qua.size());
        dataset->SetSerieName(dataset->GetSerieCount()-1, wxT("米价"));
    }

    // create line renderer and set it to dataset
    XYLineRenderer *renderer = new XYLineRenderer();
    dataset->SetRenderer(renderer);

    // add our dataset to plot
    plot->AddDataset(dataset);

    // create left and bottom number axes
    NumberAxis *leftAxis = new NumberAxis(AXIS_LEFT);
    NumberAxis *bottomAxis = new NumberAxis(AXIS_BOTTOM);

    // add axes to plot
    plot->AddAxis(leftAxis);
    plot->AddAxis(bottomAxis);

    // link axes and dataset
    plot->LinkDataVerticalAxis(0, 0);
    plot->LinkDataHorizontalAxis(0, 0);

    // set serie names to be displayed on legend

    // set legend
    plot->SetLegend(new Legend(wxCENTER, wxRIGHT));

    Chart *chart = new Chart(plot, _T("趋势图"));
    chartpanel_->SetChart(chart);
    delete []oilqua_data;
    delete []oilpri_data;
    delete []ricequa_data;
    delete []ricepri_data;
    delete []gasqua_data;
    delete []gaspri_data;
}

void CDlgReportDailyNecess::OnTimer(wxTimerEvent& event)
{
    wxTimer& timer=event.GetTimer();
    if(timer.GetId()==IDC_TIMER_SEC) {
        ShowData();//显示数据
    }
}
